
package Rete;


import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;


public class Server extends Thread{
    ArrayList<GiocatoreRete> giocatori;
    DatagramSocket socket = null;
    public Server (int porta)
    {
        inizializza();
        System.out.println("creo la socket");
        //creo thread con socket in ascolto per i giocatori che si uniranno
        try
        {
            socket = new DatagramSocket(porta);
            socket.setReuseAddress(true);
        }
        catch (SocketException ex) {Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);}
    }

    public void inizializza()
    {
        System.out.println("inizializzo il server");
        giocatori = new ArrayList<GiocatoreRete>();
    }

    public DatagramSocket getSocket()
    {
        return socket;
    }

    private ArrayList<String> getNomiGiocatori()
    {
        // funzione chiamata dal thread con la socket in ascolto---
        ArrayList<String> nomiGiocatori = new ArrayList<String>();
        for (int i=0;i<giocatori.size();i++)
        {
            nomiGiocatori.add(giocatori.get(i).getNome());
        }
        return nomiGiocatori;
    }

    private void setNomiGiocatori(ArrayList<GiocatoreRete> giocatori)
    {
        this.giocatori = giocatori;
    }

    private int aggiungiGiocatoreAllaPartita(String nomeGiocatore, String ip, int porta) //SERVER
    {
        //+++++++++++++++++++++++++++++++++
        // rispondo 0 se i giocatori sono gia' 4, 1 se ho aggiunto correttamente, 2 se c'e' un omonimo
        //+++++++++++++++++++++++++++++++++
        // funzione chiamata dal thread con la socket in ascolto---
        // controllo che i giocatori non siano già 4 e che non ci sia gia' qualcuno con quel nome,
        // poi rispondo con un boolean al thread (il quale risponderà al client tramite la socket)
        if (giocatori.size() == 4)
        {
            return 0;
        }

        int indiceOmonimo = -1;
        for (int i=0;i<giocatori.size();i++)
        {
            if (nomeGiocatore.equals(giocatori.get(i).getNome()))
            {
                indiceOmonimo = i;
            }
        }
        if (indiceOmonimo == -1) //il giocatore non era gia' in lista
        {
            giocatori.add(new GiocatoreRete(nomeGiocatore,ip,porta));
            return 1;
        }
        else
        {
            return 2;
        }
    }

    private boolean eliminaGiocatoreDallaPartita(String nome) //SERVER
    {
        // funzione chiamata dal thread con la socket in ascolto---
        // controllo che "nome" sia in "partita" e poi lo elimino
        int indiceDaEliminare = -1;
        for (int i=0;i<giocatori.size();i++)
        {
            if (nome.equals(giocatori.get(i).getNome()))
            {
                indiceDaEliminare = i;
            }
        }
        if (indiceDaEliminare == -1)
        {
            return false; //il giocatore non era in lista
        }
        else
        {
            giocatori.remove(indiceDaEliminare);
            return true;
        }
    }

    private int getNumeroGiocatori()
    {
        return giocatori.size();
    }

    public ArrayList<GiocatoreRete> getGiocatori()
    {
        return giocatori;
    }
    ///////////////////////////////////////// thread
    @Override
     public void run()
    {
        System.out.println("thread server avviato");
        boolean iniziaPartita = false;
        while (iniziaPartita == false)
        {
            String[] info = Utils.riceviStringaConInfoDaSocket(getSocket());
            String richiesta = info[0];
            String ipClient = info[1];
            int portaClient = Integer.parseInt(info[2]);

            if (richiesta.equals("iniziaPartita")) //puo' essere ricevuto solo da localhost
            {
                if (getNumeroGiocatori()==4)
                {
                    iniziaPartita = true;
                    //dico a tutti i client che si inizia
                    for (int i=0;i<4;i++)
                    {
                        System.out.println("--- DA SERVER A CLIENT ---");
                        Utils.inviaStringaSuSocket("Inizia la partita",getSocket(), getGiocatori().get(i).getIP(), getGiocatori().get(i).getPorta());
                    }
                }
                else
                {
                    //dico al client che me lo ha chiesto (127.0.0.1) che non ci sono abbastanza giocatori
                    System.out.println("--- DA SERVER A CLIENT ---");
                    Utils.inviaStringaSuSocket("Numero di giocatori: "+getNumeroGiocatori(),getSocket(), ipClient, portaClient);
                }
            }

            if (richiesta.equals("annullaPartita")) //puo' essere ricevuto solo da localhost
            {
                //dico a tutti i client che la partita e' annullata
                for (int i=0;i<getNumeroGiocatori();i++)
                {
                    System.out.println("--- DA SERVER A CLIENT ---");
                    Utils.inviaStringaSuSocket("Partita annullata",getSocket(), getGiocatori().get(i).getIP(), getGiocatori().get(i).getPorta());
                }
            }

            if (richiesta.equals("ListaGiocatori"))
            {
                String listaGiocatori = "";
                for (int i=0;i<getNumeroGiocatori();i++)
                {
                    listaGiocatori = listaGiocatori+getNomiGiocatori().get(i)+"-";
                }
                listaGiocatori = listaGiocatori.substring(0, listaGiocatori.length()-1); //per eliminare l'ultimo "-"
                System.out.println("--- DA SERVER A CLIENT ---");
                Utils.inviaStringaSuSocket(listaGiocatori,getSocket(), ipClient , portaClient);
            }

            if (richiesta.startsWith("Chiedo di entrare: "))
            {
                // chiedo di aggiungere il giocatore alla lista (con nome, ip e porta)
                StringTokenizer t = new StringTokenizer(richiesta,":");
                t.nextToken(); //butto via la stringa "Chiedo di entrare"
                String nomeGiocatore = t.nextToken().trim();
                int risultato = aggiungiGiocatoreAllaPartita(nomeGiocatore, ipClient, portaClient);
                //+++++++++++++++++++++++++++++++++
                // ricevo 0 se i giocatori sono gia' 4, 1 se ho aggiunto correttamente, 2 se c'e' un omonimo
                //+++++++++++++++++++++++++++++++++
                if (risultato == 0)
                {
                    //rispondo "Siamo gia' in 4"
                    System.out.println("--- DA SERVER A CLIENT ---");
                    Utils.inviaStringaSuSocket("Siamo gia' in 4", getSocket(), ipClient , portaClient);
                }
                if (risultato == 1)
                {
                    // gli rispondo "OK"
                    System.out.println("--- DA SERVER A CLIENT ---");
                    Utils.inviaStringaSuSocket("OK", getSocket(), ipClient , portaClient);
                    // poi invio agli altri giocatori la lista aggiornata ------------ DA FARE --------------------------------
                }
                if (risultato == 2)
                {
                    System.out.println("--- DA SERVER A CLIENT ---");
                    Utils.inviaStringaSuSocket("Nome gia' presente in lista", getSocket(), ipClient , portaClient);
                }
            }

            if (richiesta.startsWith("Voglio uscire: "))
            {
                // chiedo di eliminare il giocatore dalla lista (col nome del giocatore)
                StringTokenizer t = new StringTokenizer(richiesta,":");
                t.nextToken(); //butto via la stringa "Voglio uscire"
                String nomeGiocatore = t.nextToken().trim();
                boolean risultato = eliminaGiocatoreDallaPartita(nomeGiocatore);
                if (risultato == true)
                {
                    System.out.println("--- DA SERVER A CLIENT ---");
                    Utils.inviaStringaSuSocket("Eliminato con successo", getSocket(), ipClient , portaClient);
                }
                else
                {
                    System.out.println("--- DA SERVER A CLIENT ---");
                    Utils.inviaStringaSuSocket("Nome non presente in lista", getSocket(), ipClient , portaClient);
                }
            }
        }

    }
}
